#include "messageProcessor.h"
#include "protocol.h"
#include "room.h"
#include <string.h>
#include <errno.h>
#include <unistd.h>
int sendMessage(int sendFd, struct message msg);
void sendUserList(int sendFd);
void sendRoomList(int sendFd);
//thread func
void *messageReader(void *arg){
	initQueue();
	struct messageQueue data;
	struct message *pMsg;
	while(1){
		data=readMessage();
		pMsg=(struct message*)data.buf;
		//방 폭파해서 로비로 쫓겨난 사람에게 메세지 전달.
		if((pMsg->type==0x10)){
			struct message sMsg;
			sMsg.type=0x10;
			sMsg.length=3;
			sendMessage(data.send_fd,sMsg);
			sendRoomList(data.send_fd);
			sendUserList(data.send_fd);
		}
		if((pMsg->type&0xF0)==0x20){
			struct message sMsg;
			int updateUser=0;
			int updateRoom=0;
			//처음 유저가 서버에 접속할 때 받는 메세지
			if(pMsg->type==0x20){ 
				struct person *person=
					joinNewPerson(data.send_fd,(char*)pMsg->msg);
				struct userInfo usr;
				if(person==NULL){
					usr.userID=-1;
					usr.name[0]='\0';
				}
				else{
					usr.userID=data.send_fd;
					strcpy(usr.name,person->name);
					updateUser=1;
					updateRoom=1;
				}
				sMsg.type=0x30;
				sMsg.roomNo=0;
				sMsg.length=4+sizeof(usr);
				memmove((void*)&sMsg.msg,(void*)&usr,sizeof(usr));	

			}	
			//다른 방에 입장할 때
			if(pMsg->type==0x21){
				int roomNo=pMsg->roomNo;
				struct room *inRoom=findRoom(roomNo);
				struct person *person=findPerson(data.send_fd);
				struct roomInfo rom;
				sMsg.type=0x31;
				sMsg.roomNo=0;
				sMsg.length=4+sizeof(rom);
				if(inRoom!=NULL){
					enterRoomPerson(inRoom, person);
					rom.roomID=roomNo;	
					strcpy(rom.name,inRoom->name);
					updateUser=1;
					if(roomNo==0)
						updateRoom=1;
				}
				else{
					rom.roomID=-1;
					rom.name[0]='\0';
				}
				memmove((void*)&sMsg.msg,(void*)&rom,sizeof(rom));
			}
			//새로 방을 만들때 
			if(pMsg->type==0x22){
				char* newRoomName=(char*)pMsg->msg;
				struct person *person=findPerson(data.send_fd);
				struct room *newRoom=makeNewRoom(person,newRoomName);
				struct roomInfo rom;
				sMsg.type=0x32;
				sMsg.roomNo=0;
				sMsg.length=4+sizeof(rom);
				if(newRoom!=NULL){
					rom.roomID=newRoom->roomID;
					strcpy(rom.name,newRoom->name);
				}
				else{
					rom.roomID=-1;
					rom.name[0]='\0';
				}
				memmove((void*)&sMsg.msg,(void*)&rom,sizeof(rom));
			}
			sendMessage(data.send_fd,sMsg);
			
			if(updateUser)
				sendUserList(data.send_fd);
			if(updateRoom)
				sendRoomList(data.send_fd);
				
		}
		if(pMsg->type==0x01){
			const struct person *person=findPerson(data.send_fd);
			const struct room *curRoom=person->curRoom;
			const char *chat=(char*)pMsg->msg;
			struct personList *pl=curRoom->list;
			struct message sMsg;
			sMsg.type=0x11;
			sMsg.roomNo=0;
			strcpy((char*)sMsg.msg,chat);
			sMsg.length=4+strlen(chat)+1;
			while(pl!=NULL){
				struct person *p=pl->person;
				pl=pl->next;
				if(p==person) continue;
				sendMessage(p->fd,sMsg);	
			}

		}	

		//처리하는 과정 수행.
		//printf("read %c\n",(char)buf[0]);
	}	
}
int sendMessage(int sendFd, struct message msg){
	printf("sendType : %d\n",msg.type);
	size_t len=msg.length;
	void* buf=(void*)&msg;
	char *bufp;
   	size_t bytestowrite;
   	ssize_t byteswritten;
   	size_t totalbytes;
	int result=0;
   	
	for (bufp = buf, bytestowrite = len, totalbytes = 0;
       		bytestowrite > 0;
        	bufp += byteswritten, bytestowrite -= byteswritten) {
      	
		byteswritten = write(sendFd, bufp, bytestowrite);
      	if ((byteswritten == -1) && (errno != EINTR || errno!=EAGAIN)){
			totalbytes=-1;
         	break;
		}
      	if (byteswritten == -1)
         	byteswritten = 0;
      	totalbytes += byteswritten;
  	}
	printf("total send : %d\n",totalbytes);
	usleep(100);
	return totalbytes;
}

void sendUserList(int sendFd){
	struct message msg;
	const struct person *person=findPerson(sendFd);
	if(person==NULL) return;
   	struct personList *list=person->curRoom->list;
	msg.type=0x13;
	struct userInfo uList[10];
	int cnt=0;
	while(list!=NULL && cnt<10){
		uList[cnt].userID=list->person->fd;
		strncpy(uList[cnt].name,list->person->name,PERSON_NAME_MAX);
		list=list->next;
		cnt++;
	}
	msg.length=4+sizeof(struct userInfo)*cnt;
	memmove((void*)msg.msg,(void*)uList,sizeof(struct userInfo)*cnt);
	int i;
	for(i=0;i<cnt;i++){
		sendMessage(uList[i].userID,msg);
	}
}
void sendRoomList(int sendFd){
	struct message msg;
	struct room *rl=roomList;
	struct roomInfo rList[10];
	msg.type=0x12;
	int cnt=0;
	while(rl!=NULL){
		rList[cnt].roomID=rl->roomID;
		strncpy(rList[cnt].name, rl->name, ROOM_NAME_MAX);
		cnt++;
		rl=rl->next;
	}
	msg.length=4+sizeof(struct roomInfo)*cnt;
	if(cnt!=0){
		memmove((void*)msg.msg,(void*)rList,sizeof(struct roomInfo)*cnt);
	}

	sendMessage(sendFd,msg);
}
